package org.jeecg.modules.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.jeecg.modules.demo.bean.do_.DeptDo;
import org.jeecg.modules.demo.bean.do_.RoleDo;
import org.jeecg.modules.demo.bean.do_.UserDeptDo;
import org.jeecg.modules.demo.bean.do_.UserDo;
import org.jeecg.modules.demo.bean.vo.ModelGroupVo;
import org.jeecg.modules.demo.bean.vo.OrgTreeVo;
import org.jeecg.modules.demo.bean.vo.UserVo;
import org.jeecg.modules.demo.mapper.*;
import org.jeecg.modules.demo.service.OrgRepositoryService;
import org.jeecg.modules.system.entity.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 默认wflow的实现，集成自有系统需要自行实现接口
 * @author : willian fu
 * @date : 2022/11/29
 */
@Service
public class DefaultOrgRepositoryServiceImpl implements OrgRepositoryService {

    @Autowired
    private WflowUsersMapper usersMapper;

    @Autowired
    private WflowRolesMapper rolesMapper;

    @Autowired
    private WflowDepartmentsMapper departsMapper;

    @Autowired
    private WflowUserDepartmentsMapper userDepartmentsMapper;

    @Autowired
    private WflowUserRolesMapper userRolesMapper;

    @Autowired
    private WflowModelPermsMapper modelPermsMapper;

    @Override
    public List<ModelGroupVo.Form> getModelsByPerm(String userId) {
        return modelPermsMapper.selectByPerms(userId);
    }

    @Override
    public UserDo getUserById(String userId) {
        SysUser sysUser = usersMapper.selectById(userId);
        if (Objects.nonNull(sysUser)){
            UserDo userDo = new UserDo();
            BeanUtils.copyProperties(sysUser, userDo);
            return userDo;
        }
        return null;
    }

    @Override
    public List<OrgTreeVo> selectUsersByPy(String py) {
        return usersMapper.selectUsersByPy(py).stream()
                .peek(u -> u.setType("user")).collect(Collectors.toList());
    }

    @Override
    public List<OrgTreeVo> selectUsersByDept(String deptId) {
        return usersMapper.selectUsersByDept(deptId);
    }


    @Override
    public List<OrgTreeVo> selectUsersByDeptSys(String deptId) {
        return usersMapper.selectUsersByDeptSys(deptId);
    }
    @Override
    public List<UserDo> getUsersBatch(Collection<String> userIds) {
        try {
            return usersMapper.selectBatchIds(userIds).stream()
                    .map(u -> new UserDo(u.getId(), u.getRealname(), u.getAvatar()))
                    .collect(Collectors.toList());
        } catch (Exception e) {
            return Collections.emptyList();
        }
    }

    @Override
    public List<DeptDo> getDeptBatch(Collection<String> deptIds) {
        try {
            return departsMapper.selectBatchIds(deptIds).stream()
                    .map(u -> new DeptDo(u.getId(), u.getDepartName(), u.getLeader(), u.getParentId()))
                    .collect(Collectors.toList());
        } catch (Exception e) {
            return Collections.emptyList();
        }
    }

    @Override
    public Set<String> getUsersByDepts(Collection<String> deptIds) {
        try {
            return userDepartmentsMapper.selectList(
                    new LambdaQueryWrapper<SysUserDepart>()
                            .select(SysUserDepart::getUserId)
                            .in(SysUserDepart::getDepId, deptIds))
                    .stream().map(SysUserDepart::getUserId)
                    .collect(Collectors.toSet());
        } catch (Exception e) {
            return Collections.emptySet();
        }
    }

    @Override
    public DeptDo getDeptById(String deptId) {
        SysDepart departments = departsMapper.selectById(deptId);
        if (Objects.nonNull(departments)){
            DeptDo deptDo = new DeptDo();
            BeanUtils.copyProperties(departments, deptDo);
            return deptDo;
        }
        return null;
    }

    @Override
    public List<DeptDo> getSysAllDepts() {
        try {
            return departsMapper.selectList(null).stream()
                    .map(d -> new DeptDo(d.getId(), d.getDepartName(), d.getLeader(), d.getParentId()))
                    .collect(Collectors.toList());
        } catch (Exception e) {
            return Collections.emptyList();
        }
    }

    @Override
    public List<UserDeptDo> getSysAllUserDepts() {
        try {
            return userDepartmentsMapper.selectList(null).stream()
                    .map(d -> new UserDeptDo(d.getUserId(), d.getDepId()))
                    .collect(Collectors.toList());
        } catch (Exception e) {
            return Collections.emptyList();
        }
    }

    @Override
    public List<OrgTreeVo> getSubDeptById(String parentId) {
        return departsMapper.selectByDept(parentId);
    }

    @Override
    public List<String> getRecursiveSubDept(String parentId) {
        List<String> list = new ArrayList<>();
        loadSubDept(parentId, list);
        return list;
    }

    /**
     * 递归加载所有子部门
     * @param parentId 父部门ID
     * @param subDepts 所有子部门缓存
     */
    private void loadSubDept(String parentId, List<String> subDepts){
        List<SysDepart> departments = departsMapper.selectList(
                new LambdaQueryWrapper<SysDepart>()
                .eq(SysDepart::getParentId, parentId));
        subDepts.addAll(departments.stream().map(SysDepart::getId).collect(Collectors.toList()));
        departments.forEach(d -> loadSubDept(d.getId(), subDepts));
    }

    @Override
    public List<RoleDo> getSysAllRoles() {
        try {
            return rolesMapper.selectList(null).stream()
                    .map(r -> new RoleDo(r.getId(), r.getRoleName()))
                    .collect(Collectors.toList());
        } catch (Exception e) {
            return Collections.emptyList();
        }
    }

    @Override
    public Set<String> getUsersByRoles(List<String> roles) {
        return userRolesMapper.selectList(new LambdaQueryWrapper<SysUserRole>()
                        .select(SysUserRole::getUserId)
                        .in(SysUserRole::getRoleId, roles)).stream()
                .map(SysUserRole::getUserId).collect(Collectors.toSet());
    }

    @Override
    public String getUserSign(String userId) {
        return usersMapper.selectById(userId).getSign();
    }

    @Override
    public void updateUserSign(String userId, String signature) {
        usersMapper.updateById(SysUser.builder().id(userId).sign(signature).build());
    }

    @Override
    public UserVo getUserDetail(String userId) {
        SysUser user = usersMapper.selectById(userId);
        List<DeptDo> depts = getDeptsByUser(userId);
        List<SysRole> roles = rolesMapper.getRolesByUser(userId);
        Integer sex = user.getSex();
        boolean sexJ;
        if (sex == 1) {
            sexJ = true;
        } else {
            sexJ = false;
        }
        return UserVo.builder()
                .userId(userId)
                .username(user.getUsername())
                .sex(sexJ)
                .avatar(user.getAvatar())
                .entryDate(user.getCreateTime())
                // .leaveDate(user.getLeaveDate())
                .positions(Collections.emptyList())
                .depts(depts.stream().map(DeptDo::getDeptName).collect(Collectors.toList()))
                .roles(roles.stream().map(SysRole::getRoleName).collect(Collectors.toList()))
                .build();
    }

    @Override
    public List<DeptDo> getDeptsByUser(String userId) {
        return userDepartmentsMapper.getUserDepts(userId);
    }
}
